home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / PACKET / TFPCX2IP / TFPCX2IP.ASM < prev   
Assembly Source File  |  1997-10-25  |  27KB  |  994 lines

  1. .model large
  2. .8086
  3. ;.stack 100h
  4.  
  5. ax25_code       segment word public
  6.                 assume  cs:ax25_code, ds:ax25_code
  7.  
  8.         org 2ch
  9. phd_environ     dw ?
  10.  
  11. szczyt_kolejki  EQU     216Eh
  12.         org 100h
  13. start:  jmp install_driver
  14.  
  15. txt1:   db      'TFPCX-2-TCP/IP         Version 0.4b',13,10
  16.         db      'Packet driver that allows using TFPCX with NOS software',13,10
  17.         db      '(C) 1995 by Piotrek Kaczmarzyk, SQ6BOT',13,10,10
  18.         db      'This little piece of code is a CARDWARE - please read DOC file',13,10
  19.         db      'Free license granted to radio amateurs only.',13,10,10,'$'
  20. txt2:   db      'TFPCX V2.0 detected.',13,10,'$'
  21. txt3:   db      'Error: This program works only with TFPCX V2.0.',13,10,'$'
  22. txt4:   db      'Error: TFPCX not loaded.',13,10,'$'
  23. host:   db      'Switching TFPCX to Host Mode.',13,10,'$'
  24. JHOST:  db      27,'JHOST1',13
  25. JHOSTend:
  26. count   dw      0
  27. packet_int_no   db      60h     ; default packet interrupt number
  28. bak_es  dw      0
  29. bak_si  dw      0
  30. bak_cx  dw      0
  31. bufadr  dw      0
  32. bufseg  dw      0
  33. bufofs  dw      0
  34. data_s  dw      0
  35. s_len   dw      0       ; dlugosc ramki
  36. s_frm   dw      0       ; adres obecnie analizowanej ramki
  37. s_pos   dw      0       ; pozycja w ramce
  38. s_pos_org       dw      0
  39. s_prev  dw      0       ; poprzednia ramka
  40. s_cnt   dw      0
  41.  
  42. HostMode:
  43.         mov     bx,offset JHOST
  44. nxt:    mov     ah,3
  45.         mov     al,[bx]
  46.         int     0FDh
  47.         inc     bx
  48.         cmp     bx,offset JHOSTend
  49.         jne     nxt
  50.         ret
  51.  
  52. ;==========================================================================
  53. proc_5E60:
  54.         lea     ax,[bx+28h]
  55.         mov     [bx+08h],ax
  56.         mov     word ptr [bx+0Ch],0000h
  57.         ret
  58.  
  59. proc_5E6C:
  60.         push    bp
  61.         mov     bp,sp
  62.         sub     sp,0004h
  63.         pushf
  64.         cli
  65.         mov     ax,ds:[14E8h]
  66.         dec     word ptr ds:[14E8h]
  67.         or      ax,ax
  68.         jnz     loc_5E82
  69.         stc
  70.         jmp     return
  71.         ; < ERROR - NO MORE FREE BUFFERS
  72. loc_5E82:
  73.         mov     bx,ds:[12F2h]
  74.         call    proc_5E94
  75.         mov     [bp-02h],ax
  76.         popf
  77.         mov     ax,[bp-02h]
  78.         clc
  79. return:
  80.         mov     sp,bp
  81.         pop     bp
  82.         ret
  83.  
  84. create_frame:
  85.         push    ax
  86.         push    bx
  87.         push    cx
  88.         push    si
  89.         mov     bx,ax
  90. add_next_char:
  91.         cmp     cx,0000h
  92.         je      w_buforze
  93.         mov     al,es:[si]
  94.         push    bx
  95.         call    proc_5E0A        ; al = char, bx = buffer address
  96.         pop     bx
  97.         dec     cx
  98.         inc     si
  99.         jmp     add_next_char
  100. w_buforze:
  101.         pop     si
  102.         pop     cx
  103.         pop     bx
  104.         pop     ax
  105.         ret
  106.  
  107. proc_5E0A:
  108.         push    bp
  109.         mov     bp,sp
  110.         push    ax
  111.         push    si
  112.         mov     si,bx
  113.         mov     ax,[si+0Ah]
  114.         inc     word ptr [si+0Ah]
  115.         test    al,1Fh
  116.         jnz     loc_5E2C
  117.         call    proc_5E6C
  118.         mov     bx,ax
  119.         mov     ax,[si+06h]
  120.         call    proc_5EB6
  121.         add     ax,0004h
  122.         mov     [si+08h],ax
  123. loc_5E2C:
  124.         mov     al,[bp-02h]
  125.         mov     bx,[si+08h]
  126.         mov     [bx],al
  127.         inc     word ptr [si+08h]
  128.         pop     si
  129.         mov     sp,bp
  130.         pop     bp
  131.         ret
  132.  
  133. sendpkt:
  134.         call    rst_ds
  135.         call    proc_5E6C       ; allocate
  136.         call    create_frame
  137.         mov     bx,ax
  138.         call    proc_5E60       ; refresh
  139.         mov     ax,ds:[2034]
  140.         mov     [si+0Eh],ax
  141.         mov     byte ptr [bx+10h],02h
  142.         mov     byte ptr [bx+11h],00h
  143.         mov     byte ptr [bx+12h],00h    ; nr_modemu = [14E6]
  144.         call    proc_5834       ; send_it
  145.         clc
  146.         mov dh,NO_ERROR
  147.         ret
  148.  
  149. rst_ds:
  150.         push    cs
  151.         pop     ds
  152.         push    ax
  153.         mov     ax,data_s
  154.         mov     ds,ax
  155.         pop     ax
  156.         ret
  157.  
  158. no_more_buffers:
  159.         jmp     pkterror
  160.  
  161. proc_5834:
  162.         push    bp
  163.         mov     bp,sp
  164.         sub     sp,0002h
  165.         push    bx
  166.         push    si
  167.         mov     al,[bx+12h]
  168.         sub     ah,ah
  169.         mov     [bp-02h],ax
  170.         mov     si,ax
  171.         shl     si,1
  172.         inc     word ptr [si+1470h]
  173.         cmp     word ptr ds:[14E8h],0040h
  174.         jbe     out_of_buffers
  175.         call    proc_5E60
  176.         pushf
  177.         cli
  178.         mov     bx,[bp-02]
  179.         shl     bx,1
  180.         shl     bx,1
  181.         mov     ax,[bx+1532h]
  182.         mov     bx,[bp-04]
  183.         call    proc_5EB6
  184.         mov     bx,[bp-02]
  185.         cmp     byte ptr [bx+78DEh],00h
  186.         jnz     problems
  187.         mov     ax,bx
  188.         call    final_send
  189.         jmp     koncowka
  190. problems:
  191.         mov     byte ptr [bx+1FFCh],01h
  192. koncowka:
  193.         popf
  194.         pop     si
  195.         mov     sp,bp
  196.         pop     bp
  197.         ret
  198.  
  199. out_of_buffers:
  200.         mov     bx,[bp-04h]
  201.         mov     ax,ds:[2170h]
  202.         call    proc_5EB6
  203.         pop     si
  204.         mov     sp,bp
  205.         pop     bp
  206.         ret
  207.  
  208. final_send:
  209.         push    bp
  210.         mov     bp,sp
  211.         sub     sp,0002h
  212.         push    ax
  213.         cmp     al,ds:[201Eh]
  214.         jb      loc1
  215.         jmp     something
  216. loc1:
  217.         mov     bl,al
  218.         sub     bh,bh
  219.         cmp     [bx+20E6h],bh
  220.         jnz     loc2
  221.         jmp     something
  222. loc2:
  223.         shl     bx,1
  224.         cmp     byte ptr [bx+798Eh],00h
  225.         jz      loc3
  226.         mov     al,30h
  227.         mul     byte ptr [bx+798Fh]
  228.         mov     bx,ax
  229.         mov     word ptr [bx+78ACh],0001h
  230.         mov     sp,bp
  231.         pop     bp
  232.         ret
  233. loc3:
  234.         mov     bl,[bp-04h]
  235.         sub     bh,bh
  236.         shl     bx,1
  237.         mov     al,1Ch
  238.         mul     byte ptr [bx+798Fh]
  239.         mov     bx,ax
  240.         add     bx,20FEh
  241.         mov     [bp-02h],bx
  242.         cmp     byte ptr [bx+0Ah],00h
  243.         jz      something
  244.         pushf
  245.         cli
  246.         mov     bx,[bp-02h]
  247.         mov     al,[bx+14h]
  248.         sub     ah,ah
  249.         jmp     loc4
  250. loc10:
  251.         mov     bl,[bp-04h]
  252.         sub     bh,bh
  253.         cmp     [bx+1518h],bh
  254.         jz      loc9
  255. loc6:
  256.         mov     ax,0001h
  257. loc5:
  258.         mov     bx,[bp-02h]
  259.         mov     [bx+16h],ax
  260.         mov     bx,[bp-02h]
  261.         mov     byte ptr [bx+14h],01h
  262.         jmp     loc7
  263. loc9:
  264.         mov     bl,[bp-04h]
  265.         sub     bh,bh
  266.         cmp     [bx+20D6h],bh
  267.         jz      loc6
  268.         mov     al,[bx+20D6h]
  269.         sub     ah,ah
  270.         jmp     loc5
  271. loc8:
  272.         mov     bx,[bp-02h]
  273.         mov     word ptr [bx+16h],0001h
  274.         mov     byte ptr [bx+14h],02h
  275.         jmp     loc7
  276. loc4:
  277.         or      ax,ax
  278.         jz      loc10
  279.         sub     ax,0005h
  280.         jz      loc8
  281. loc7:
  282.         popf
  283.         mov     sp,bp
  284.         pop     bp
  285.         ret
  286.  
  287. something:
  288.         mov     ah,[bp-04h]
  289.         sub     al,al
  290.         or      ax,8001h
  291.         call    proc_5D62
  292.         mov     sp,bp
  293.         pop     bp
  294.         ret
  295.  
  296. proc_5D62:
  297.         push    di
  298.         push    si
  299.         mov     dx,ax
  300.         mov     cl,08h
  301.         mov     si,ax
  302.         and     si,7F00h
  303.         shr     si,cl
  304.         mov     ax,si
  305.         shl     si,1
  306.         add     si,1520h
  307.         mov     di,ax
  308.         shl     di,1
  309.         shl     di,1
  310.         add     di,1530h
  311.         cmp     word ptr [si],0000h
  312.         je      loc_a
  313.         mov     bx,[si]
  314.         mov     ax,ds:[2170h]
  315.         call    proc_5EB6
  316.         mov     word ptr [si],0000h
  317. loc_a:  mov     bx,di
  318.         call    proc_5DF0
  319.         pop     si
  320.         pop     di
  321.         ret
  322.  
  323. proc_5DF0:
  324.         push    si
  325.         cmp     [bx],bx
  326.         je      loc_b
  327.         mov     si,bx
  328. loc_c:  mov     bx,[si]
  329.         call    proc_5E94
  330.         mov     bx,ax
  331.         mov     ax,ds:[2170h]
  332.         call    proc_5EB6
  333.         cmp     [si],si
  334.         jne     loc_c
  335. loc_b:  pop     si
  336.         ret
  337.  
  338. proc_5E94:
  339.         push    bp
  340.         mov     bp,sp
  341.         push    bx
  342.         push    si
  343.         pushf
  344.         cli
  345.         mov     bx,[bp-02h]
  346.         mov     ax,[bx]
  347.         mov     si,[bx+2]
  348.         mov     [si],ax
  349.         mov     ax,[bx+02h]
  350.         mov     bx,[bx]
  351.         mov     [bx+02h],ax
  352.         popf
  353.         mov     ax,[bp-02h]
  354.         pop     si
  355.         mov     sp,bp
  356.         pop     bp
  357.         ret
  358.  
  359. proc_5EB6:
  360.         push    bp
  361.         mov     bp,sp
  362.         push    ax
  363.         push    bx
  364.         push    di
  365.         push    si
  366.         pushf
  367.         cli
  368.         mov     bx,[bp-02h]
  369.         mov     ax,[bx]
  370.         mov     si,[bp-04h]
  371.         mov     [si],ax
  372.         mov     [si+02h],bx
  373.         mov     di,[si]
  374.         mov     [di+02h],si
  375.         mov     [bx],si
  376.         popf
  377.         mov     ax,[bp-04h]
  378.         pop     si
  379.         pop     di
  380.         mov     sp,bp
  381.         pop     bp
  382.         ret
  383.  
  384. ;=====================================================
  385. ; RECEIVING PART
  386. ;=====================================================
  387.  
  388.  
  389. doupcallnow:
  390.         pushf
  391.         push    bp
  392.         push    bx
  393.         push    ax
  394.         push    cx
  395.         push    dx
  396.         push    di
  397.         push    si
  398.         push    ds
  399.         push    es
  400.         mov     bx,szczyt_kolejki
  401. next_frame:
  402.         call    rst_ds
  403.         mov     bx,[bx]
  404.         mov     cx,bx
  405.         cmp     bx,szczyt_kolejki
  406.         jne     short is_packet
  407.         jmp     no_packet
  408. is_packet:
  409.         call    rst_ds
  410.         call    proc_5E60       ; refresh
  411.         push    cs
  412.         pop     ds
  413.         mov     count,0
  414. copy_next_byte:
  415.         call    rst_ds
  416.         mov     ax,[bx+0Ch]
  417.         cmp     ax,[bx+0Ah]
  418.         je      copy_end
  419.         call    proc_5E3C
  420.         push    bx
  421.         push    cs
  422.         pop     ds
  423.         mov     bx,offset buf
  424.         add     bx,count
  425.         cmp     bx,offset over_buf
  426.         jae     no_packet2
  427.         mov     ds:[bx],al
  428.         inc     count
  429.         pop     bx
  430.         jmp     copy_next_byte
  431.  
  432. no_packet2:
  433.         pop     bx
  434.         jmp     no_packet
  435.  
  436. copy_end:
  437.         push    cs
  438.         pop     ds
  439.         push    bx
  440.         call    DoUpCall
  441.         pop     bx
  442.  
  443. ;        mov     [bx+28h],0A8A8h
  444.         jmp     next_frame
  445.  
  446. no_packet:
  447.         pop     es
  448.         pop     ds
  449.         pop     si
  450.         pop     di
  451.         pop     dx
  452.         pop     cx
  453.         pop     ax
  454.         pop     bx
  455.         pop     bp
  456.         popf
  457.  
  458.         mov     [bp-08h],ax
  459.         cmp     ax,szczyt_kolejki
  460.         db      0EAh,0B1h,46h
  461. jump2:  dw      0
  462.  
  463.  
  464. proc_5E3C:
  465.         push    si
  466.         mov     ax,[bx+0Ch]
  467.         inc     word ptr [bx+0Ch]
  468.         test    al,1Fh
  469.         jnz     loc_z
  470.         mov     si,[bx+08h]
  471.         mov     ax,[si-24h]
  472.         add     ax,0004h
  473.         mov     [bx+08h],ax
  474. loc_z:
  475.         mov     si,[bx+08h]
  476.         inc     word ptr [bx+08h]
  477.         mov     al,[si]
  478.         sub     ah,ah
  479.         pop     si
  480.         ret
  481.  
  482. drvr_class      db 9    ;driver's class - default is 9 that is AX.25
  483. driver_name     db 'Packet driver overlay for TFPCX',0
  484.  
  485.                 even
  486. old_packet_int  dw 0,0  ;saves software interrupt vector
  487. receive_upcall  dw 0,0  ;keeps application "upcall" routine address
  488.  
  489. ;==============================================================
  490. ;Service routine for software interrupt to control the driver
  491.  
  492. ;  Packet Driver Error numbers
  493. NO_ERROR        equ     0       ;no error at all.
  494. BAD_HANDLE      equ     1       ;invalid handle number
  495. NO_CLASS        equ     2       ;no interfaces of specified class found
  496. NO_TYPE         equ     3       ;no interfaces of specified type found
  497. NO_NUMBER       equ     4       ;no interfaces of specified number found
  498. BAD_TYPE        equ     5       ;bad packet type specified
  499. NO_MULTICAST    equ     6       ;this interface does not support multicast
  500. CANT_TERMINATE  equ     7       ;this packet driver cannot terminate
  501. BAD_MODE        equ     8       ;an invalid receiver mode was specified
  502. NO_SPACE        equ     9       ;operation failed because of insufficient space
  503. TYPE_INUSE      equ     10      ;the type had previously been accessed, and not released.
  504. BAD_COMMAND     equ     11      ;the command was out of range, or not implemented
  505. CANT_SEND       equ     12      ;the packet couldn't be sent (usually hardware error)
  506. CANT_SET        equ     13      ;hardware address couldn't be changed (more than 1 handle open)
  507. BAD_ADDRESS     equ     14      ;hardware address has bad length or format
  508. CANT_RESET      equ     15      ;Couldn't reset interface (more than 1 handle open).
  509. BAD_IOCB        equ     16      ;an invalid iocb was specified
  510.  
  511. regs_w  struc                           ; stack offsets of incoming regs
  512. _ES     dw      ?
  513. _DS     dw      ?
  514. _bp     dw      ?
  515. _DI     dw      ?
  516. _SI     dw      ?
  517. _DX     dw      ?
  518. _CX     dw      ?
  519. _BX     dw      ?
  520. _AX     dw      ?
  521. _IP     dw      ?
  522. _CS     dw      ?
  523. _F      dw      ?                       ; flags, Carry flag is bit 0
  524. regs_w  ends
  525.  
  526. CY      equ     0001h
  527. EI      equ     0200h
  528.  
  529. regs_b  struc                           ; stack offsets of incoming regs
  530.         dw      ?                       ; es, ds, bp, di, si are 16 bits
  531.         dw      ?
  532.         dw      ?
  533.         dw      ?
  534.         dw      ?
  535. _DL     db      ?
  536. _DH     db      ?
  537. _CL     db      ?
  538. _CH     db      ?
  539. _bl     db      ?
  540. _bh     db      ?
  541. _AL     db      ?
  542. _AH     db      ?
  543. regs_b  ends
  544.  
  545. DRVR_ISR:                       ;service interrupt vector points here
  546.                                 ;application layer calls enter this point
  547.                                 ;via a software interrupt
  548.         jmp exec_command        ;entry point must be a jump
  549.         db 'PKT DRVR',0         ;followed by this string
  550.  
  551. exec_command:           ;packet driver command executor
  552.         sti             ;don't lock interrupts
  553.         push ax         ;save registers on stack
  554.         push bx
  555.         push cx
  556.         push dx
  557.         push si
  558.         push di
  559.         push bp
  560.         push ds
  561.         push es
  562.         mov  bp,sp              ;bp=sp so we can address pushed registers
  563.         and _F[bp],not CY       ;Clear carry on exit
  564.         mov bx,cs               ;make ds=cs
  565.         mov ds,bx
  566.         mov bl,ah               ;execute command given by ah
  567.         mov bh,0
  568.         cmp bx,26
  569.         jnc f_above_25
  570.         add bx,bx
  571.         call [functions+bx]
  572. DRVR_ISR_return:
  573.         mov _DH[bp],dh          ;pass dh-now to dh-on-exit
  574.         sbb ax,ax
  575.         and ax,CY
  576.         or _F[bp],ax            ;pass carry-now to carry-on-exit
  577.         pop es
  578.         pop ds
  579.         pop bp
  580.         pop di
  581.         pop si
  582.         pop dx
  583.         pop cx
  584.         pop bx
  585.         pop ax
  586.         iret
  587.  
  588. f_above_25:
  589.         call f_not_implemented
  590.         jmp short DRVR_ISR_return
  591.  
  592.         even
  593. functions       label   word
  594.         dw      f_not_implemented       ;0
  595.         dw      f_driver_info           ;1
  596.         dw      f_access_type           ;2
  597.         dw      f_release_type          ;3
  598.         dw      f_send_pkt              ;4
  599.         dw      f_terminate             ;5
  600.         dw      f_get_address           ;6
  601.         dw      f_reset_interface       ;7
  602.         dw      f_stop                  ;8
  603.         dw      f_not_implemented       ;9
  604.         dw      f_get_parameters        ;10
  605.         dw      f_not_implemented       ;11
  606.         dw      f_as_send_pkt           ;12
  607.         dw      f_drop_pkt              ;13
  608.         dw      f_not_implemented       ;14
  609.         dw      f_not_implemented       ;15
  610.         dw      f_not_implemented       ;16
  611.         dw      f_not_implemented       ;17
  612.         dw      f_not_implemented       ;18
  613.         dw      f_not_implemented       ;19
  614.         dw      f_set_rcv_mode          ;20
  615.         dw      f_get_rcv_mode          ;21
  616.         dw      f_set_multicast_list    ;22
  617.         dw      f_get_multicast_list    ;23
  618.         dw      f_get_statistics        ;24
  619.         dw      f_set_address           ;25
  620.  
  621. f_driver_info:
  622.         mov dh,drvr_class               ;driver class
  623.         mov _CH[bp],dh
  624.         mov _AL[bp],1                   ;basic flag
  625.         mov _DX[bp],0                   ;driver type
  626.         mov _CL[bp],0                   ;driver number
  627.         mov _BX[bp],0                   ;driver version
  628.         mov _DS[bp],ds                  ;driver name pointer
  629.         mov _SI[bp],offset driver_name
  630.         mov dh,NO_ERROR
  631.         clc
  632.         ret
  633.  
  634. f_access_type:
  635.         mov bx,_BX[bp]
  636.         cmp al,drvr_class       ;our class ?
  637.         jnz wrong_class
  638.         cmp bx,0FFFFh           ;generic type ?
  639.         jz type_OK
  640.         cmp bx,0                ;our type ?
  641.         jnz wrong_type
  642. type_OK:
  643.         cmp dl,0                ;generic num ?
  644.         jnz wrong_num
  645.         mov ax,receive_upcall   ;check if handle busy
  646.         or ax,receive_upcall+2
  647.         jnz busy_handle
  648.         mov receive_upcall,di   ;store receiver upcall
  649.         mov ax,es
  650.         mov receive_upcall+2,ax
  651.         mov _AX[bp],0           ;return handle=0
  652.         clc
  653.         mov dh,NO_ERROR
  654.         ret
  655.  
  656. wrong_class:
  657.         stc
  658.         mov dh,NO_CLASS
  659.         ret
  660. wrong_type:
  661.         stc
  662.         mov dh,NO_TYPE
  663.         ret
  664. wrong_num:
  665.         stc
  666.         mov dh,NO_NUMBER
  667.         ret
  668. busy_handle:
  669.         stc
  670.         mov dh,TYPE_INUSE
  671.         ret
  672. pkterror:
  673.         stc
  674.         mov dh,CANT_SEND
  675.         ret
  676.  
  677. f_stop: jmp short clear_upcall
  678.  
  679. f_release_type:
  680.         cmp _BX[bp],0           ;handle=0 ?
  681.         jnz wrong_handle
  682.         mov ax,receive_upcall   ;is receiver upcall defined?
  683.         or ax,receive_upcall+2
  684.         jz wrong_handle         ;jump if not
  685. clear_upcall:
  686.         xor ax,ax               ;receiver upcall := 0:0
  687.         mov receive_upcall,ax   ;this means "upcall address is not valid"
  688.         mov receive_upcall+2,ax
  689.         clc
  690.         mov dh,NO_ERROR
  691.         ret
  692.  
  693. wrong_handle:
  694.         stc
  695.         mov dh,BAD_HANDLE
  696.         ret
  697.  
  698. f_send_pkt:
  699.         mov es,_DS[bp]          ;es:si=packet address, cx=packet length
  700.         jmp sendpkt
  701.  
  702. f_terminate:
  703.         clc
  704.         mov dh,NO_ERROR
  705.         ret
  706.  
  707. f_get_address:
  708.         xor cx,cx       ;return zero-length address
  709.         clc
  710.         mov dh,NO_ERROR
  711.         ret
  712.  
  713. f_reset_interface:      jmp short f_not_implemented
  714. f_get_parameters:       jmp short f_not_implemented
  715. f_as_send_pkt:          jmp short f_not_implemented
  716. f_drop_pkt:             jmp short f_not_implemented
  717. f_set_rcv_mode:         jmp short f_not_implemented
  718. f_get_rcv_mode:         jmp short f_not_implemented
  719. f_set_multicast_list:   jmp short f_not_implemented
  720. f_get_multicast_list:   jmp short f_not_implemented
  721.  
  722. f_get_statistics:       jmp short f_not_implemented
  723.  
  724. f_set_address:          jmp short f_not_implemented
  725.  
  726. f_not_implemented:              ;non-implemented functions jump here
  727.         stc                     ;set carry to indicate an error
  728.         mov dh,BAD_COMMAND      ;error code = BAD_COMMAND
  729.         ret
  730.  
  731.  
  732. DoUpCall:               ;input: RxFrameData contains a valid packet (CRC is OK)
  733.                         ;       RxFrameLen contains its length
  734.         push ds
  735.         push es
  736.         push si
  737.         push di
  738.  
  739.         mov cx,count            ;load packet length
  740.         mov ax,receive_upcall   ;is there a valid upcall address ?
  741.         or ax,receive_upcall+2
  742.         jz DoUpCall_ret         ;jump if there is not
  743.  
  744.         mov ax,0                ;flag=0 - first upcall
  745.         mov bx,0                ;handle = 0
  746.         mov di,0                ;set es:di = NULL
  747.         mov es,di
  748.         call dword ptr [receive_upcall] ;first upcall
  749.         mov ax,es               ;check if application returned
  750.         or ax,di                ;valid buffer pointer
  751.         jz DoUpCall_ret         ;jump if not
  752.  
  753.         mov si,di               ;make si=di before we alter di (for second upcall)
  754.         mov bx,offset buf       ;copy the packet to es:di
  755.         mov cx,count            ;packet length (exclude CRC)
  756. CopyLoop: mov al,[bx]           ;loop over packet bytes
  757.           inc bx                ;would movsb do the job ?
  758.           mov es:[di],al
  759.           inc di
  760.           loop CopyLoop
  761.         mov cx,count            ;again packet len for second call
  762.         mov ax,es               ;make ds=es (is not same as cs now !)
  763.         mov ds,ax
  764.         mov bx,0                ;handle 0
  765.         mov ax,1                ;flag=1 - second upcall
  766.  
  767.         call dword ptr cs:[receive_upcall]      ;second upcall
  768. ;we have to use cs: addressing in above call because we modified ds
  769.  
  770. DoUpCall_ret:
  771.         pop di
  772.         pop si
  773.         pop es
  774.         pop ds
  775.         ret
  776.  
  777. buf:
  778.         db      200h    dup (?)
  779. over_buf:
  780.  
  781. print_following_string: ;prints string following the call - modifies bx !
  782.                         ;string must following "call print_following_string"
  783.                         ;_must_ end with NULL character !
  784.         pop bx          ;pop return address from the stack
  785.         push ax         ;so we know where the char. string is
  786.         push dx
  787. print_next_char:
  788.           mov dl,cs:[bx]        ;load next character
  789.           inc bx
  790.           and dl,dl             ;NULL char ?
  791.           jz string_end         ;exit this loop if so
  792.           mov ah,2              ;otherwise print it
  793.           int 21h
  794.         jmp short print_next_char
  795. string_end:
  796.         pop dx
  797.         pop ax
  798.         push bx                 ;push new return address on stack
  799.         ret
  800.  
  801. SkipBlanks:             ;mov to first non-SPACE nor TAB char.
  802.                         ;ds:[bx] = string address
  803. SkipThisChar:
  804.         mov al,es:[bx]     ;load next char.
  805.         inc bx          ;increment pointer
  806.         cmp al,' '      ;space ?
  807.         jz SkipThisChar ;jump if SPACE
  808.         cmp al,9        ;TAB ?
  809.         jz SkipThisChar ;jump if TAB
  810.         dec bx          ;if not SPACE nor TAB move pointer back
  811.         ret             ;ds:bx=address of non-blank character
  812.                         ;al=this character
  813.  
  814. ReadOptions:
  815.         push ax
  816.         push bx
  817.         push cx
  818.         push dx
  819.         mov bx,81h              ;load offset to command line arguments
  820. NextOption:
  821.         call SkipBlanks         ;al=next non-blank char
  822.         cmp al,13               ;carriage return ?
  823.         clc
  824.         jz ReadOptions_ret
  825.         cmp al,'-'              ;minus sign ?
  826.         jz InterpreteOption     ;if so go and interprete following chars
  827. ReadOptions_err:
  828.         stc
  829. ReadOptions_ret:
  830.         pop dx
  831.         pop cx
  832.         pop bx
  833.         pop ax
  834.         ret             ;carry=1 => results are _not_ valid
  835.  
  836. InterpreteOption:       ;interprete an option
  837.                         ;ds:bx=address of '-' char.
  838.         inc bx
  839.         mov al,es:[bx]     ;load char after '-'
  840.         inc bx          ;move pointer futher
  841.         cmp al,'?'
  842.         je  OptionUsage
  843.         cmp al,'i'
  844.         je  Opt_interrupt
  845.  
  846.         call UnknownOption      ;if non of the above says the option
  847.                                 ;was not recognized
  848.         jmp ReadOptions_err
  849.  
  850. Opt_interrupt:
  851.         call ReadHexNumber
  852.         mov packet_int_no,dl
  853.         jmp short NextOption
  854.  
  855. OptionUsage:
  856.         call    Print_following_string
  857.         db      'Usage:',10,10,13
  858.         db      ' -?              - this help text',10,13
  859.         db      ' -i<hex_int_no>  - set interrupt vector',10,13
  860.         db      10,0
  861.         clc
  862.         jmp  NextOption
  863.  
  864. UnknownOption:          ;say the option not recognized
  865.         push bx
  866.         call Print_following_string
  867.         db 'Unknown option: -',0
  868.         mov dl,al
  869.         mov ah,2
  870.         int 21h
  871.         call Print_following_string
  872.         db 13,10,0
  873.         pop bx
  874.         ret
  875.  
  876. ReadHexDigit:           ;es:bx = digit pointer
  877.         mov al,es:[bx]
  878.         cmp al,'0'
  879.         jc ReadHexDigit_ret     ;jump if below '0'
  880.           cmp al,'9'+1
  881.           cmc
  882.           jc ReadHexDigit_lett   ;jump if above '9'
  883.             sub al,'0'
  884.             jmp short ReadHexDigit_ret
  885. ReadHexDigit_lett:
  886.         cmp al,'a'
  887.         jc ReadHexDigit_ret       ;jump if below 'a'
  888.           cmp al,'f'+1
  889.           cmc
  890.           jc ReadHexDigit_ret     ;jump if above 'f'
  891.             sub al,'a'-10
  892. ReadHexDigit_ret:
  893.         ret             ;carry=1 => not a hex digit, al=char.
  894.                         ;carry=0 => hex digit indeed, al=value
  895.  
  896. ReadHexNumber:
  897.         push cx
  898.         mov cl,4
  899.         mov dx,0
  900. ReadNextHexDigit:
  901.         call ReadHexDigit
  902.         jc ReadHexNumber_ret
  903.           inc bx
  904.           shl dx,cl     ;multiply dx by 16
  905.           or dl,al      ;add the digit just read
  906.         jmp short ReadNextHexDigit
  907. ReadHexNumber_ret:
  908.         pop cx
  909.         ret             ;dx=the number,
  910.                         ;ds:bx *char where the interpretation stopped
  911.                         ;al=this character
  912.  
  913. install_driver:
  914.         call ReadOptions
  915.         jnc DoPrintParam
  916.         jmp BadUsage
  917. DoPrintParam:
  918. ;       call PrintParameters
  919.  
  920. ;--------------------------------
  921.  
  922.         push    ds
  923.         push    cs
  924.         pop     ds
  925.         mov     ah,09h
  926.         mov     dx,offset txt1
  927.         int     21h
  928.         mov     ax,35FDh
  929.         int     21h
  930.         mov     si,bx
  931.         mov     ax,es:[si+4]
  932.         cmp     ax,4E35h
  933.         jne     no_tfpcx
  934.         mov     ah,0FEh
  935.         int     0FDh
  936.         cmp     ax,0200h
  937.         jne     no_v2
  938.         mov     ah,09h
  939.         mov     dx,offset txt2
  940.         int     21h
  941.  
  942.         pop     es
  943.         call    ReadOptions
  944.  
  945.         xor     ax,ax
  946.         mov     es,ax
  947.         mov     si,8*4+2
  948.         mov     ax,es:[si]
  949.         mov     ds,ax
  950.         cli
  951.         mov     bx,46Abh
  952.         mov     byte ptr [bx],0EAh
  953.         mov     word ptr [bx+1],offset doupcallnow
  954.         mov     word ptr [bx+3],cs
  955.         mov     cx,ds:[0FC0h]
  956.         mov     ax,ds
  957.         push    cs
  958.         pop     ds
  959.         mov     bx,offset jump2
  960.         mov     [bx],ax
  961.         mov     data_s,cx
  962.         sti
  963.         mov     ah,25h
  964.         mov     al,packet_int_no
  965.         mov     dx,offset DRVR_ISR
  966.         int     21h
  967.         mov     dx,offset host
  968.         mov     ah,9
  969.         int     21h
  970.         call    HostMode
  971.         mov     ah,31h
  972.         mov     dx,offset koniec
  973.         shr     dx,1
  974.         int     21h
  975.  
  976. no_v2:
  977.         mov     dx,offset txt3
  978.         jmp     no_
  979. no_tfpcx:
  980.         mov     dx,offset txt4
  981. no_:
  982.         mov     ah,09h
  983.         int     21h
  984. n33:    mov     ax,4C01h
  985.         int     21h
  986. BadUsage:
  987.         call    print_following_string
  988.         db      'Bad options - type TFPCX2IP -? to get info',13,10,0
  989.         jmp     n33
  990.  
  991. koniec:
  992.         ends    ax25_code
  993.         end     start
  994.